package com.hksj.aqm.service;

import cn.hutool.core.date.DateUtil;
import com.hksj.aqm.constant.Pm25IndexEnum;
import com.hksj.aqm.mapper.Pm25Mapper;
import com.hksj.aqm.query.DayPm25Query;
import com.hksj.aqm.query.Pm25Query;
import com.hksj.aqm.query.PropertyAvgQuery;
import com.hksj.aqm.util.AQIUtil;
import com.hksj.aqm.vo.*;
import com.hksj.base.query.AlarmQuery;
import com.hksj.base.service.DefaultAlarmService;
import com.hksj.base.service.DefaultDeviceService;
import com.hksj.base.vo.AlarmRecordVO;
import com.hksj.base.vo.DeviceVO;
import com.hksj.common.core.common.DevicePropertyConstants;
import com.hksj.common.core.util.EasyExcelUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class Pm25Service {
    @Autowired
    private Pm25Mapper pm25Mapper;
    @Autowired
    private DefaultDeviceService defaultDeviceService;
    @Autowired
    private DefaultAlarmService defaultAlarmService;

    /**
     * 查询pm2.5 各等级的占比数
     * @param query
     * @return
     */
    public List<Pm25RateVO> listPm25Rate(Pm25Query query) {
        //查设备
        List<Pm25RateVO> res = new ArrayList<>();
        List<DeviceVO> deviceList = pm25Mapper.listDevice(query);
        List<PropertyAvgVO> all = new ArrayList<>();
        if (!ObjectUtils.isEmpty(deviceList)){
            //按产品分组查询设备上报记录值平均值
            Map<String, List<DeviceVO>> productDeviceMap = deviceList.stream().collect(Collectors.groupingBy(DeviceVO::getProductId));
            Date now = new Date();
            Long startTime = DateUtil.beginOfDay(now).getTime();
            Long endTime = DateUtil.endOfDay(now).getTime();
            for (String productId : productDeviceMap.keySet()) {
                PropertyAvgQuery propertyAvgQuery = new PropertyAvgQuery();
                propertyAvgQuery.setProperty(DevicePropertyConstants.PM25_PROPERTY_NAME);
                propertyAvgQuery.setTableName(defaultDeviceService.getTableName(productId));
                propertyAvgQuery.setStartTime(startTime);
                propertyAvgQuery.setEndTime(endTime);
                List<String> deviceIdList = productDeviceMap.get(productId).stream().map(DeviceVO::getId).collect(Collectors.toList());
                propertyAvgQuery.setDeviceIdList(deviceIdList);
                List<PropertyAvgVO> propertyAvgList = pm25Mapper.listPropertyAvg(propertyAvgQuery);
                all.addAll(propertyAvgList);
            }
        }
        if (!ObjectUtils.isEmpty(all)){
            for (PropertyAvgVO propertyAvgVO : all) {
                propertyAvgVO.setLevel(AQIUtil.getPm25Level(propertyAvgVO.getValue()));
            }
            Map<Integer, List<PropertyAvgVO>> levelMap = all.stream().collect(Collectors.groupingBy(PropertyAvgVO::getLevel));
            for (Integer level : levelMap.keySet()) {
                res.add(new Pm25RateVO(level, Pm25IndexEnum.getRemarkByValue(level),levelMap.getOrDefault(level,new ArrayList<>()).size()));
            }
        }
        return res;
    }

    /**
     * 获取每日pm2.5指数
     * @param query
     * @return
     */
    public AqmCalendarVO listDayPm25Index(DayPm25Query query){
        //每日指数
        AqmCalendarVO aqmCalendarVO = new AqmCalendarVO();
        List<DayPm25IndexVO> dayPm25IndexList = new ArrayList<>();
        List<DeviceVO> deviceList = pm25Mapper.listDevice(query);
        List<DayPropertyAvgVO> all = new ArrayList<>();
        if (!ObjectUtils.isEmpty(deviceList)){
            Map<String, List<DeviceVO>> productDeviceMap = deviceList.stream().collect(Collectors.groupingBy(DeviceVO::getProductId));
            Long startTime = DateUtil.beginOfDay(query.getStartTime()).getTime();
            Long endTime = DateUtil.endOfDay(query.getEndTime()).getTime();
            for (String productId : productDeviceMap.keySet()) {
                PropertyAvgQuery propertyAvgQuery = new PropertyAvgQuery();
                propertyAvgQuery.setProperty(DevicePropertyConstants.PM25_PROPERTY_NAME);
                propertyAvgQuery.setTableName(defaultDeviceService.getTableName(productId));
                propertyAvgQuery.setStartTime(startTime);
                propertyAvgQuery.setEndTime(endTime);
                propertyAvgQuery.setProductId(productId);
                List<String> deviceIdList = productDeviceMap.get(productId).stream().map(DeviceVO::getId).collect(Collectors.toList());
                propertyAvgQuery.setDeviceIdList(deviceIdList);
                List<DayPropertyAvgVO> dayPropertyAvgList = pm25Mapper.listDayPropertyAvg(propertyAvgQuery);
                all.addAll(dayPropertyAvgList);
            }
        }
        if (!ObjectUtils.isEmpty(all)){
            Map<String, List<DayPropertyAvgVO>> dayAvgMap = all.stream().collect(Collectors.groupingBy(DayPropertyAvgVO::getDay));
            for (String day : dayAvgMap.keySet()) {
                Double avg = dayAvgMap.get(day).stream().mapToDouble(DayPropertyAvgVO::getValue).average().orElse(0.0D);
                DayPm25IndexVO dayPm25IndexVO = new DayPm25IndexVO();
                dayPm25IndexVO.setDay(day);
                dayPm25IndexVO.setAvg(AQIUtil.calculateAQI_PM25(avg));
                dayPm25IndexVO.setLevel(AQIUtil.getPm25Level(avg));
                dayPm25IndexVO.setRemark(Pm25IndexEnum.getRemarkByValue(dayPm25IndexVO.getLevel()));
                dayPm25IndexList.add(dayPm25IndexVO);
            }
        }

        //各pm2.5等级占比数量
        Map<Integer, List<DayPm25IndexVO>> levelNumMap = new HashMap<>();
        if (!ObjectUtils.isEmpty(dayPm25IndexList)){
            levelNumMap = dayPm25IndexList.stream().collect(Collectors.groupingBy(DayPm25IndexVO::getLevel));
        }

        List<Pm25RateVO> pm25RateList = new ArrayList<>();
        for (int i = 1; i < 7; i++) {
            List<DayPm25IndexVO> dayPm25IndexVOS = levelNumMap.get(i);
            if (ObjectUtils.isEmpty(dayPm25IndexVOS)){
                pm25RateList.add(new Pm25RateVO(i,Pm25IndexEnum.getRemarkByValue(i),0));
            }else{
                pm25RateList.add(new Pm25RateVO(i,Pm25IndexEnum.getRemarkByValue(i),dayPm25IndexVOS.size()));
            }
        }
        aqmCalendarVO.setDayPm25IndexList(dayPm25IndexList);
        aqmCalendarVO.setPm25RateList(pm25RateList);
        return aqmCalendarVO;
    }

    /**
     * 导出报警数据
     * @param query
     * @param response
     */
    public void exportAlarm(AlarmQuery query, HttpServletResponse response) {
        query.setDisAblePage(true);
        List<AlarmRecordVO> records = defaultAlarmService.pageAlarmHistory(query).getRecords();
        List<AqmAlarmExportVO> res = new ArrayList<>();
        if (!ObjectUtils.isEmpty(records)){
            for (int i = 0; i < records.size(); i++) {
                AlarmRecordVO alarmRecordVO = records.get(0);
                AqmAlarmExportVO aqmAlarmExportVO = new AqmAlarmExportVO();
                aqmAlarmExportVO.setSortNo(i + 1);
                aqmAlarmExportVO.setAddr(defaultDeviceService.getAddr(alarmRecordVO));
                aqmAlarmExportVO.setDeviceName(alarmRecordVO.getName());
                aqmAlarmExportVO.setProperty(alarmRecordVO.getProperty());
                aqmAlarmExportVO.setValue(alarmRecordVO.getValue());
                aqmAlarmExportVO.setCreateTime(DateUtil.formatDateTime(alarmRecordVO.getCreateTime()));
                res.add(aqmAlarmExportVO);
            }
        }

        String fileName = new StringBuffer()
                .append("空气质量监测报警")
                .append(new SimpleDateFormat("_yyyyMMddHHmmss").format(new Date()))
                .toString();
        EasyExcelUtil.exportExcelData(response,fileName,res,AqmAlarmExportVO.class);
    }
}
